home *** CD-ROM | disk | FTP | other *** search
/ Carousel / CAROUSEL.cdr / mactosh / code / p_serlib.sit / Serial Library Source Code / serial.readFileTilStr.dll.c < prev    next >
C/C++ Source or Header  |  1989-07-27  |  13KB  |  457 lines

  1. /***********************************************************************/
  2. /*    
  3. /*    serial.readFileTilStr.dll.c
  4. /*    by Atul Butte
  5. /*    Copyright ⌐ 1989 by Microsoft Corporation
  6. /*    All Rights Reserved
  7. /*
  8. /*    version 1.0
  9. /*    
  10. /*    
  11. /*    This CALL/REGISTER will read from the serial port until the specifed
  12. /*    string is read up to 255 characters. The characters are stored in
  13. /*    a file.
  14. /*    
  15. /*    Excel usage:
  16. /*    
  17. /*    = Register( "serial library", "serial.readTilStr", "IHDJCD" )
  18. /*    = Call( ref, portNumber, matchStr, maxTime, readConfigStr, fileName )
  19. /*    
  20. /*    where
  21. /*        portNumber        = number of port (1 = modem, 2 = printer)
  22. /*        matchStr        = keep reading until we read this string
  23. /*        maxTime            = maximum amount of time to wait for characters
  24. /*                          in 1/60 second units
  25. /*        readConfigStr    = configuration of communications protocol, etc
  26. /*        fileName        = name of file in which to store characters
  27. /*    
  28. /***********************************************************************/
  29.  
  30. /***********************************************************************/
  31. /*
  32. /*    D E F I N E S
  33. /*
  34. /***********************************************************************/
  35.  
  36. #define ROUTINE_NAME    "serial.readFileTilStr"
  37. #define hNIL 0L
  38. #define pNIL 0L
  39. #define kcchBuff        64
  40.  
  41. /***********************************************************************/
  42. /*
  43. /*    I N C L U D E S
  44. /*
  45. /***********************************************************************/
  46.  
  47. #include "serial.h"
  48. #include "error.h"
  49. #include "get_port.h"
  50. #include "interpret.h"
  51. #include "get_read_flags.h"
  52.  
  53. /***********************************************************************/
  54. /*
  55. /*    P R O T O T Y P E S
  56. /*
  57. /***********************************************************************/
  58.  
  59. void initialize_next( Ptr pnxt, char *pstMatch );
  60. char check_for_match( char cRead, unsigned char cCurrentChar, unsigned char cMatchLength, char *pstMatch, Ptr pnxt );
  61.  
  62. short open_file( char *stFilename );
  63. void close_file( short refnum, char *pch, unsigned short dch );
  64. Boolean store_character( short refnum, char cRead, char *pch, unsigned short *dch );
  65.  
  66. /***********************************************************************/
  67. /*
  68. /*    main
  69. /*
  70. /***********************************************************************/
  71.  
  72. pascal short main( port, pstMatch, timeDur, pszConfig, pstFilename )
  73.  
  74.     unsigned short            port;                    /* serial port to use */
  75.     char                    *pstMatch;                /* keep reading until we read this string */
  76.     unsigned long            timeDur;                /* maximum time to wait for chars (in ticks) */
  77.     char                    *pszConfig;                /* communications configuration string */
  78.     register char            *pstFilename;            /* name of file in which to save characters */
  79.     
  80. {
  81.     register OSErr            err;                    /* result code from Toolbox routines */
  82.     ParamBlockRec            param;                    /* parameter block for read/write */
  83.     
  84.     Boolean                    fEcho = false;            /* flag for echoing characters */
  85.     Boolean                    fEdit = false;            /* flag for allowing edit characters */
  86.     Boolean                    fStripLF = false;        /* flag for stripping line feeds */
  87.     Boolean                    fStrip8Bit = false;        /* flag for stripping high bit */
  88.     Boolean                    fAddLF = false;            /* flag for adding LF after CR */
  89.     Boolean                    fIgnore = false;        /* flag for ignoring escape chars */
  90.     
  91.     Handle                    hnxt;                    /* handle to the next table */
  92.     register Ptr            pnxt;                    /* pointer to the next table */
  93.     long                    cchBuff = 0;            /* number of characters waiting in read buffer */
  94.     register unsigned long    timeStop;                /* time at which to stop */
  95.     short                    refIn;                    /* reference number for input port */
  96.     short                    refOut;                    /* reference number for output port */
  97.     char                    chRead;                    /* buffer used to read a character */
  98.     register char            ch;                        /* character read */
  99.     char                    echoBackspace[3];        /* characters to send to echo Backspace */
  100.     char                    echoLinefeed;            /* characters to send to echo Linefeed */
  101.     register unsigned char    cchMatched;                /* number of characters matching so far */
  102.     register unsigned char    cchMatch;                /* number of characters to match */
  103.     
  104.     char                    *pch;                    /* buffer used in file reading */
  105.     unsigned short            ichBuff = 0;            /* index in buffer */
  106.     short                    refFile;                /* reference number for file */
  107.  
  108.     RememberA0();
  109.     SetUpA4();
  110.     
  111.     if( pstFilename == pNIL ) {
  112.         display_error( "The fifth parameter must be a file name." );
  113.         RestoreA4( );
  114.         return( errParam );
  115.     }
  116.     if( *pstFilename == 0 ) {
  117.         display_error( "The fifth parameter must be a file name." );
  118.         RestoreA4( );
  119.         return( errParam );
  120.     }
  121.         
  122.     if( pszConfig == pNIL ) {
  123.         display_error( "The fourth parameter must be a configuration string." );
  124.         RestoreA4( );
  125.         return( errParam );
  126.     }
  127.     if( pstMatch == pNIL ) {
  128.         display_error( "The second parameter must be a string to match." );
  129.         RestoreA4( );
  130.         return( errParam );
  131.     }
  132.     if( *pstMatch == 0 ) {
  133.         display_error( "You must specify a string to match with at least one character." );
  134.         RestoreA4( );
  135.         return( errParam );
  136.     }
  137.  
  138.     err = get_port( port, &refIn, &refOut );
  139.     if( err != noErr ) {
  140.         display_error( "Illegal port number." );
  141.         RestoreA4( );
  142.         return( err );
  143.     }
  144.         
  145.     pch = NewPtr( kcchBuff );
  146.     if( pch == pNIL ) {
  147.         display_error( "Not enough memory to allocate buffer." );
  148.         RestoreA4( );
  149.         return( errMemory );
  150.     }
  151.     ichBuff = 0;
  152.     
  153.     if( ( refFile = open_file( pstFilename ) ) == 0 ) {
  154.         RestoreA4( );
  155.         return( errDiskWrite );
  156.     }
  157.     
  158.     get_read_flags( pszConfig, &fEcho, &fEdit, &fStripLF, &fStrip8Bit, &fAddLF, &fIgnore );
  159.     
  160.     if( !fIgnore ) {
  161.         err = interpret( pstMatch );
  162.         if( err != noErr ) {
  163.             RestoreA4( );
  164.             return( errStrFormat );
  165.         }
  166.     }
  167.     
  168.     cchMatched = 1;
  169.     cchMatch = *pstMatch;
  170.     if( cchMatch > 1 ) {
  171.         hnxt = NewHandle( (long) *pstMatch + 1 );
  172.         HLock( hnxt );
  173.         pnxt = *hnxt;
  174.         initialize_next( pnxt, pstMatch );
  175.     }
  176.     
  177.     if( fEcho ) {
  178.         echoBackspace[0] = kchBackspace;
  179.         echoBackspace[1] = ' ';
  180.         echoBackspace[2] = kchBackspace;
  181.         if( fAddLF ) {
  182.             echoLinefeed = kchLinefeed;
  183.         }
  184.     }
  185.     
  186.     timeStop = TickCount( ) + timeDur;
  187.     
  188.     while( true ) {
  189.     
  190.         if( ( timeDur != 0 ) && ( TickCount( ) >= timeStop ) ) {
  191.             break;
  192.         }
  193.         err = SerGetBuf( refIn, &cchBuff );
  194.         if( err != noErr ) {
  195.             display_error( "Error trying to count buffer." );
  196.             err = errSerialGetBuf;
  197.             goto CleanExit;
  198.         }
  199.         if( cchBuff == 0 )
  200.             continue;
  201.         param.ioParam.ioReqCount = 1;
  202.         param.ioParam.ioBuffer = &chRead;
  203.         param.ioParam.ioRefNum = refIn;
  204.         err = PBRead( ¶m, false );
  205.         if( err != noErr ) {
  206.             display_error( "Error reading from serial port." );
  207.             err = errSerialRead;
  208.             goto CleanExit;
  209.         }
  210.         ch = chRead;
  211.         if( ( (ch == kchBackspace) || (ch == kchDelete) ) && (fEdit) ) {
  212.             if( fEcho ) {
  213.                 param.ioParam.ioReqCount = 3;
  214.                 param.ioParam.ioRefNum = refOut;
  215.                 param.ioParam.ioBuffer = echoBackspace;
  216.                 err = PBWrite( ¶m, false );
  217.                 if( err != noErr ) {
  218.                     display_error( "Error echoing backspace to serial port." );
  219.                     err = errSerialWrite;
  220.                     goto CleanExit;
  221.                 }
  222.             }
  223.         } else if( fEcho ) {
  224.             param.ioParam.ioReqCount = 1;
  225.             param.ioParam.ioRefNum = refOut;
  226.             param.ioParam.ioBuffer = &chRead;
  227.             err = PBWrite( ¶m, false );
  228.             if( err != noErr ) {
  229.                 display_error( "Error echoing to serial port." );
  230.                 err = errSerialWrite;
  231.                 goto CleanExit;
  232.             }
  233.             if( (ch == kchReturn) && (fAddLF) ) {
  234.                 param.ioParam.ioReqCount = 1;
  235.                 param.ioParam.ioRefNum = refOut;
  236.                 param.ioParam.ioBuffer = &echoLinefeed;
  237.                 err = PBWrite( ¶m, false );
  238.                 if( err != noErr ) {
  239.                     display_error( "Error echoing linefeed to serial port." );
  240.                     err = errSerialWrite;
  241.                     goto CleanExit;
  242.                 }
  243.             }
  244.         }
  245.         if( fStrip8Bit ) {
  246.             ch &= 0x7F;
  247.         }
  248.         
  249.         if( (ch == kchLinefeed) && (fStripLF) ) {
  250.         } else {
  251.             if( !store_character( refFile, ch, pch, &ichBuff ) ) {
  252.                 err = errDiskWrite;
  253.                 goto CleanExit;
  254.             }
  255.             cchMatched = check_for_match( ch, cchMatched, cchMatch, pstMatch, pnxt );
  256.             if( cchMatched > cchMatch ) /* if we found a match */
  257.                 break;
  258.         }
  259.     }
  260.     
  261.     if( cchMatched > cchMatch ) {
  262.         err = noErr;
  263.     } else {
  264.         err = errTimeOut;
  265.     }
  266.     
  267. CleanExit:
  268.  
  269.     close_file( refFile, pch, ichBuff );
  270.     if( cchMatch > 1 )
  271.         DisposHandle( hnxt );
  272.     RestoreA4();
  273.     return( err );
  274. }
  275.  
  276. /***********************************************************************/
  277. /*
  278. /*    initialize_next
  279. /*
  280. /***********************************************************************/
  281.  
  282. void initialize_next( pnxt, pstMatch )
  283.  
  284.     register Ptr            pnxt;                    /* pointer to the next table */
  285.     char                    *pstMatch;                /* keep reading until we read this string */
  286.     
  287. {
  288.     register unsigned long    i = 1, j = 0;            /* index through match string */
  289.     register unsigned char    cchMatch = *pstMatch;    /* number of characters to match */
  290.     
  291.     pnxt[1] = 0;
  292.     do {
  293.         if( ( j == 0 ) || ( pstMatch[i] == pstMatch[j] ) ) {
  294.             i++;
  295.             j++;
  296.             pnxt[i] = j;
  297.         } else {
  298.             j = pnxt[j];
  299.         }
  300.     } while( i <= cchMatch );
  301. }
  302.  
  303. /***********************************************************************/
  304. /*
  305. /*    check_for_match
  306. /*
  307. /***********************************************************************/
  308.  
  309. char check_for_match( ch, cchMatched, cchMatch, pstMatch, pnxt )
  310.  
  311.     register char            ch;                        /* character read */
  312.     register unsigned char    cchMatched;                /* number of characters matching so far */
  313.     register unsigned char    cchMatch;                /* number of characters to match */
  314.     char                    *pstMatch;                /* keep reading until we read this string */
  315.     register Ptr            pnxt;                    /* pointer to the next table */
  316.     
  317. {
  318.     if( cchMatch == 1 ) {
  319.         if( ch == pstMatch[1] ) {
  320.             return( 2 );
  321.         } else {
  322.             return( 1 );
  323.         }
  324.     } else {
  325.         do {
  326.             if( ( cchMatched == 0 ) || ( ch == pstMatch[cchMatched] ) ) {
  327.                 cchMatched++;
  328.                 break;
  329.             } else {
  330.                 cchMatched = pnxt[cchMatched];
  331.             }
  332.         } while( cchMatched <= cchMatch );
  333.         
  334.         return( cchMatched );
  335.     }
  336. }
  337.  
  338. /***********************************************************************/
  339. /*
  340. /*    open_file
  341. /*
  342. /***********************************************************************/
  343.  
  344. short open_file( pstFilename )
  345.  
  346.     register char            *pstFilename;            /* name of file in which to save characters */
  347.  
  348. {
  349.     short                    refFile;                /* reference number for file */
  350.     register OSErr            err;                    /* result code from Toolbox routines */
  351.  
  352.     err = FSOpen( pstFilename, 0, &refFile );
  353.     if( err == fnfErr ) {
  354.         err = Create( pstFilename, 0, 'XCEL', 'TEXT' );
  355.         if( err != noErr ) {
  356.             display_error( "Error creating file." );
  357.             return( 0 );
  358.         }
  359.         err = FSOpen( pstFilename, 0, &refFile );
  360.         if( err != noErr ) {
  361.             display_error( "Error opening file." );
  362.             return( 0 );
  363.         }
  364.     } else if( err == noErr ) {
  365.         err = SetEOF( refFile, 0L );
  366.         if( err != noErr ) {
  367.             display_error( "Error deleting existing file." );
  368.             return( 0 );
  369.         }
  370.     } else {
  371.         display_error( "Error opening file." );
  372.         return( 0 );
  373.     }
  374.     return( refFile );
  375. }
  376.  
  377. /***********************************************************************/
  378. /*
  379. /*    close_file
  380. /*
  381. /***********************************************************************/
  382.  
  383. void close_file( refFile, pch, ichBuff )
  384.  
  385.     short                    refFile;                /* reference number for file */
  386.     char                    *pch;                    /* buffer used in file reading */
  387.     unsigned short            ichBuff;                /* index in buffer */
  388.     
  389. {
  390.     register OSErr            err;                    /* result code from Toolbox routines */
  391.     long                    cch;                    /* number of character left in buffer */
  392.     
  393.     if( ichBuff > 0 ) {
  394.         cch = ichBuff;
  395.         err = FSWrite( refFile, &cch, pch );
  396.         if( err == dskFulErr ) {
  397.             display_error( "Disk full error." );
  398.         } else if( err == vLckdErr ) {
  399.             display_error( "The volume is locked." );
  400.         } else if( err != noErr ) {
  401.             display_error( "Error in writing to file." );
  402.         }
  403.     }
  404.     
  405.     err = FSClose( refFile );
  406.     if( err != noErr ) {
  407.         display_error( "Error closing file." );
  408.     }
  409.     
  410.     DisposPtr( pch );
  411. }
  412.  
  413. /***********************************************************************/
  414. /*
  415. /*    store_character
  416. /*
  417. /***********************************************************************/
  418.  
  419. Boolean store_character( refFile, ch, pch, pichBuff )
  420.  
  421.     short                    refFile;                /* reference number for file */
  422.     register char            ch;                        /* character read */
  423.     char                    *pch;                    /* buffer used in file reading */
  424.     unsigned short            *pichBuff;                /* index in buffer */
  425.     
  426. {
  427.     register OSErr            err;                    /* result code from Toolbox routines */
  428.     long                    cch;                    /* number of character left in buffer */
  429.     
  430.     if( *pichBuff < kcchBuff ) {
  431.         pch[*pichBuff] = ch;
  432.         ( *pichBuff )++;
  433.     } else {
  434.         cch = kcchBuff;
  435.         err = FSWrite( refFile, &cch, pch );
  436.         if( err == dskFulErr ) {
  437.             display_error( "Disk full error." );
  438.             return( false );
  439.         } else if( err == vLckdErr ) {
  440.             display_error( "The volume is locked." );
  441.             return( false );
  442.         } else if( err != noErr ) {
  443.             display_error( "Error in writing to file." );
  444.             return( false );
  445.         }
  446.         
  447.         *pichBuff = 1;
  448.         *pch = ch;
  449.     }
  450.     return( true );
  451. }
  452.  
  453. #include "get_port.c"
  454. #include "interpret.c"
  455. #include "get_read_flags.c"
  456.  
  457.